exports.createApplication = function(req,res){

    //参数获取
    var bodyParams = req.routeInfo.bodyParams;

    //生成应用令牌
    var appKey    = common.createAppKeyStr();

    //生成应用密钥
    var appSecret = common.createAppSecretStr();

    //原子层私有IP地址
    var atomicIP = 0;

    //原子层端口号
    var atomicPort = 0;

    //聚合层私有IP地址
    var aggregationIp = 0;

    //聚合层端口号
    var aggregationPort = 0;

    //管理层私有IP地址
    var managerIp = 0;

    //管理层端口号
    var managerPort = 0;
    
    //可用ip池
    var ipArr = [];

    //可用端口池
    var portArr = [];

    //用户网络名称
    var userNetwork = "";

    //用户基本信息
    var userInfo = {};  

    //新增应用的ID
    var applicationId = 0;

    //操作日志记录
    var actionLogs = [];

    /*
     * 查询用户网络的IP与端口使用范围（判断用户是否生成了用户网络）
     */
    function searchUserNetworkInfo(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.easydCloudNetworkUsedSearch.Request_Api_Url + "/cnu_uid/" + bodyParams.cma_uid,  
                method : 'GET'
            },
            function (data) {

                if(data.result.data.length <= 0){
                    return RES.errorResponse(res,"检测到您还未生成用户网络，请先生成用户网络");
                }

                //获取用户网络相关信息
                var networkInfo = data.result.data[0];
        
                //保存用户网络
                userNetwork = networkInfo.cnu_network_name;

                //创建可用IP数组
                for(var i = 2; i <= 254; i++){
                    var ip = networkInfo.cnu_ip_1 + "." + networkInfo.cnu_ip_2 + "." + networkInfo.cnu_ip_3 + "." + i
                    ipArr.push(ip)
                }   

                //创建可用端口数组
                for(var i = parseInt(networkInfo.cnu_start_port);i<parseInt(networkInfo.cnu_end_port);i++){
                    portArr.push(i)
                }

                actionLogs.push("操作记录：=> 用户网络信息验证成功");

                cb();

            }
        )
    }

    /*
     * 获取用户配额信息
     */
    function searchUserInfo(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.userSearch.Request_Api_Url + "/u_id/" + bodyParams.cma_uid,  
                method : 'POST',                    
                data   : {
                    fields : "u_username,u_application_max"
                }
            },
            function (data) {

                //获取用户相关信息
                userInfo = data.result.data[0];

                cb();

            }
        )

    }

    /*
     *  判断该用户的应用相关限制
     *  1.名称不能重复
     *  2.应用数不能超过最大上限数
     */
    function searchUserApplication(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.easydCloudMemberApplicationSearch.Request_Api_Url + "/cma_uid/" + bodyParams.cma_uid + "/cma_is_delete/0",  
                method : 'POST',                    
                data   : {
                    fields : "cma_name,cma_id"
                }
            },
            function (data) {

                //判断名称是否重复
                var isUsedName = data.result.data.some((item) => {
                    return bodyParams.cma_name == item.cma_name; 
                })

                if(isUsedName){
                    return RES.errorResponse(res,"应用名称不能重复，请重新填写");
                }

                //判断用户是否已达到应用创建上限
                if(data.result.data.length >= userInfo.u_application_max){
                    return RES.errorResponse(res,"该用户应用已达到最大上限，无法再创建新的应用");
                }

                actionLogs.push("操作记录：=> 用户创建应用所需参数验证完成");

                cb();

            }
        )
    }

    /*
     * 新增用户应用
     */
    function addUserApplication(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.easydCloudMemberApplicationAdd.Request_Api_Url,  
                method : 'POST',                    
                data   : {
                    cma_uid         : bodyParams.cma_uid,
                    cma_name        : bodyParams.cma_name,
                    cma_describe    : bodyParams.cma_describe,
                    cma_apid        : bodyParams.cma_apid,
                    cma_app_key     : appKey,
                    cma_type        : bodyParams.cma_type,
                    cma_app_secret  : appSecret,
                    cma_create_time : common.nowTime(false)
                }
            },
            function (data) {

                //保存新增应用的ID
                applicationId = data.result;

                actionLogs.push("操作记录：=> 用户应用新增成功");

                cb();

            }
        )
    }

    /*
     * 根据应用类型生成应用的配额配置信息
     */
    function addUserApplicationQuotaConfig(cb){

        //判断应用类型 0-内容管理系统
        if(bodyParams.cma_type == 0){

            R.SEND_HTTP(
                req,
                res,
                {
                    url    : CORE_APIConfig.coreAPI.easydCloudCmsApplicationQuotaAdd.Request_Api_Url,  
                    method : 'POST',                    
                    data   : {
                        ccaq_cmaid       : applicationId,
                        ccaq_create_time : common.nowTime(false)
                    }
                },
                function (data) {

                    actionLogs.push("操作记录：=> 根据应用类型生成应用的配额配置成功");
    
                    cb();
    
                }
            )
        
        //暂时只有内容管理系统
        }else{

            cb();

        }

    }
    

    /*
     * 根据用户选择的产品类型创建独立数据库
     */
    function createApplicationDb(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.cloudCreateApplicationDb.Request_Api_Url,  
                method : 'POST',                    
                data   : {
                    appKey  : appKey,
                    appType : bodyParams.cma_type

                }
            },
            function (data) {

                actionLogs.push("操作记录：=> 应用数据库创建成功");

                cb();

            }
        )

    }


    /*
     * 获取用户已使用的端口以及IP地址
     */
    function searchUserUsedIpAndPort(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.easydCloudMemberApplicationContainerSearch.Request_Api_Url + "/cmac_uid/" + bodyParams.cma_uid,  
                method : 'GET'
            },
            function (data) {

                //获取用户的已使用IP和端口
                var usedIpArr   = [];
                var usedPortArr = [];

                var usedData = data.result.data;

                for(var i=0;i<usedData.length;i++){

                    //保存已使用的IP地址
                    var ip = usedData[i].cmac_ip;
                    usedIpArr.push(ip);

                    //保存已使用的端口号
                    usedPortArr.push(usedData[i].cmac_out_port)

                }

                //去除已使用的IP和端口号，形成新的IP和端口数组池
                var noUsedIpArr   = common.arrToHeavy(ipArr,usedIpArr)
                var noUsedPortArr = common.arrToHeavy(portArr,usedPortArr)

                //取出前3个可以用的IP和端口，等待分配使用
                atomicIP        = noUsedIpArr[0];
                aggregationIp   = noUsedIpArr[1];
                managerIp       = noUsedIpArr[2];

                atomicPort      = noUsedPortArr[0];
                aggregationPort = noUsedPortArr[1];
                managerPort     = noUsedPortArr[2];

                actionLogs.push("操作记录：=> 私有IP地址和端口号生成成功");

                cb();

            }
        )

    }

    /*
     * 根据用户所选则的应用产品，复制相关的原子层应用业务到用户的项目目录（不含主框架部分）
     */
    function createAtomicApplicationBussiness(cb){

        //模板目录
        var productDir = "";

        //用户应用目录
        var userApplicationDir = "/UserApplication/"+userInfo.u_username+"/"+appKey+"/atomicServer";
        
        //根据应用类型选择相应的项目模板
        if(bodyParams.cma_type == 0){
           productDir = "/EasydProduct/CmsBaseBussiness/atomic/."
        }else if(bodyParams.cma_type == 1){
           productDir = "/EasydProduct/ShopBaseBussiness/atomic/."
        }else{
           return RES.errorResponse(res,"没有找到相关类型的应用，请检查");  
        }

        R.Ssh_exec_dockerCommand(`${DockerSH.CopyAppBussinessTemplate} ${productDir} ${userApplicationDir}`,function(rs){

            if(rs.length > 0){
                return RES.errorResponse(res,"用户应用原子层项目创建失败，请重新尝试");  
            }else{

                actionLogs.push("操作记录：=> 用户应用原子层项目创建成功");

                cb();
            }

        })
      

    }


    /*
     * 创建原子层服务容器
     * 容器参数解析：
     * 参数1：端口号
     * 参数2：容器名称
     * 参数3：用户主项目目录
     * 参数4：容器分配的IP地址
     * 参数5：加入的用户网络
     * 参数6：数据库名称
     */
    function createAtomicLayerContainer(cb){

        var dockerParams = [
            atomicPort,
            appKey+"_atomic",
            userInfo.u_username + "/" + appKey,
            atomicIP,
            userNetwork,
            appKey
        ].join(" ");

  
        R.Ssh_exec_dockerCommand(`${DockerSH.CreateAtomicLayerAppContainer} ${dockerParams}`,function(rs){


            if(rs.indexOf('Error') != -1){

                return RES.errorResponse(res,"用户原子层服务容器创建失败，请重新尝试");  

            }else{

                actionLogs.push("操作记录：=> 用户原子层服务容器创建成功");

                cb();
            }

        })

    }

    /*
     * 保存应用原子层容器信息
     */
    function createAtomicContainerRecord(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.easydCloudMemberApplicationContainerAdd.Request_Api_Url,  
                method : 'POST',                    
                data   : {
                    cmac_name        : appKey+"_atomic",
                    cmac_ip          : atomicIP,
                    cmac_in_port     : '80',
                    cmac_out_port    : atomicPort,
                    cmac_network     : userNetwork,
                    cmac_cmaid       : applicationId,
                    cmac_create_time : common.nowTime(false),
                    cmac_uid         : bodyParams.cma_uid,
                    cmac_type        : '0'

                }
            },
            function (data) {

                actionLogs.push("操作记录：=> 原子层应用容器信息保存成功");

                cb();

            }
        )
    }

    /*
     * 根据用户所选则的应用产品，复制相关的聚合层应用业务到用户的项目目录（不含主框架部分）
     */
    function createAggregationApplicationBussiness(cb){

        //模板目录
        var productDir = "";

        //用户应用目录
        var userApplicationDir = "/UserApplication/"+userInfo.u_username+"/"+appKey+"/aggregationServer";
        // var userApplicationDir = "/UserApplication/limaomao/easyd_dec1ed7a24/aggregationServer";
        
        //根据应用类型选择相应的项目模板
        if(bodyParams.cma_type == 0){
           productDir = "/EasydProduct/CmsBaseBussiness/aggregation/."
        }else if(bodyParams.cma_type == 1){
           productDir = "/EasydProduct/ShopBaseBussiness/aggregation/."
        }else{
           return RES.errorResponse(res,"没有找到相关类型的应用，请检查");  
        }

        R.Ssh_exec_dockerCommand(`${DockerSH.CopyAppBussinessTemplate} ${productDir} ${userApplicationDir}`,function(rs){

            if(rs.length > 0){
                return RES.errorResponse(res,"用户应用聚合层项目创建失败，请重新尝试");  
            }else{

                actionLogs.push("操作记录：=> 用户应用聚合层项目创建成功");

                cb();
            }

        })
      

    }

    /*
     * 创建聚合层服务容器
     * 容器参数解析：
     * 参数1：端口号
     * 参数2：用户主项目目录
     * 参数3：加入的用户网络
     * 参数4：原子层IP地址
     * 参数5：容器名称
     * 参数6：容器IP地址
     */
    function createAggregationLayerContainer(cb){

        var dockerParams = [
            aggregationPort,
            userInfo.u_username + "/" + appKey,
            userNetwork,
            atomicIP,
            appKey + "_aggregation",
            aggregationIp
        ].join(" ");

  
        R.Ssh_exec_dockerCommand(`${DockerSH.CreateAggregationLayerAppContainer} ${dockerParams}`,function(rs){

            if(rs.indexOf('Error') != -1){

                return RES.errorResponse(res,"用户聚合层服务容器创建失败，请重新尝试");  

            }else{

                actionLogs.push("操作记录：=> 用户聚合层服务容器创建成功");

                cb();
            }

        })

    }

     /*
     * 保存应用聚合层容器信息
     */
    function createAggregationContainerRecord(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.easydCloudMemberApplicationContainerAdd.Request_Api_Url,  
                method : 'POST',                    
                data   : {
                    cmac_name        : appKey+"_aggregation",
                    cmac_ip          : aggregationIp,
                    cmac_in_port     : '3000',
                    cmac_out_port    : aggregationPort,
                    cmac_network     : userNetwork,
                    cmac_cmaid       : applicationId,
                    cmac_create_time : common.nowTime(false),
                    cmac_uid         : bodyParams.cma_uid,
                    cmac_type        : '1'

                }
            },
            function (data) {

                actionLogs.push("操作记录：=> 聚合层应用容器信息保存成功");

                cb();

            }
        )
    }

    /*
     * 根据应用类型创建管理层项目到主项目目录
     */
    function createManagerApplicationBussiness(cb){

        //模板目录
        var productDir = "";

        //用户应用目录
        var userApplicationDir = "/UserApplication/"+userInfo.u_username+"/"+appKey+"/managerServer";
        //var userApplicationDir = "/UserApplication/limaomao/easyd_8e3e008b27/managerServer";
        
        //根据应用类型选择相应的项目模板
        if(bodyParams.cma_type == 0){
           productDir = "/EasydProduct/CmsBaseBussiness/manager/."
        }else if(bodyParams.cma_type == 1){
           productDir = "/EasydProduct/ShopBaseBussiness/manager/."
        }else{
           return RES.errorResponse(res,"没有找到相关类型的应用，请检查");  
        }

        R.Ssh_exec_dockerCommand(`${DockerSH.CopyAppBussinessTemplate} ${productDir} ${userApplicationDir}`,function(rs){

            if(rs.length > 0){
                return RES.errorResponse(res,"用户应用管理层项目创建失败，请重新尝试");  
            }else{

                actionLogs.push("操作记录：=> 用户应用管理层项目创建成功");

                cb();
            }

        })


    }


    /*
     * 创建管理层服务容器
     * 容器参数解析：
     * 参数1：端口号
     * 参数2：容器名称
     * 参数3：加入的用户网络
     * 参数4：容器Ip
     * 参数5：用户主项目目录
     */
    function createManagerLayerContainer(cb){

        var dockerParams = [
            managerPort,
            appKey + "_manager",
            userNetwork,
            managerIp,
            userInfo.u_username + "/" + appKey
        ].join(" ");

        R.Ssh_exec_dockerCommand(`${DockerSH.CreateManagerLayerAppContainer} ${dockerParams}`,function(rs){

            if(rs.indexOf('Error') != -1){

                return RES.errorResponse(res,"用户管理层服务容器创建失败，请重新尝试");  

            }else{

                actionLogs.push("操作记录：=> 用户管理层服务容器创建成功");

                cb();
            }

        })

    }

    /*
     * 修改管理层所要访问的聚合层IP地址写入，管理层的动态IP配置文件
     */
    function updateManagerRequestIp(cb){

        var userApplicationDir = "/UserApplication/"+userInfo.u_username+"/"+appKey+"/managerServer/static/ipconfig.js";
        
        //最终请求的聚合层完成地址
        var requestIp = config.server.ip + ":" + aggregationPort;

        R.Ssh_exec_dockerCommand(`${DockerSH.UpdateManagerRequestIp} ${requestIp} ${userApplicationDir}`,function(rs){

            if(rs.length > 0){
                return RES.errorResponse(res,"更新管理层请求聚合层接口地址失败，请重新尝试");  
            }else{

                actionLogs.push("操作记录：=> 更新管理层请求聚合层接口地址成功");

                cb();
            }

        })

    }

    /*
     * 保存应用管理层容器信息
     */
    function createManagerContainerRecord(cb){

        R.SEND_HTTP(
            req,
            res,
            {
                url    : CORE_APIConfig.coreAPI.easydCloudMemberApplicationContainerAdd.Request_Api_Url,  
                method : 'POST',                    
                data   : {
                    cmac_name        : appKey+"_manager",
                    cmac_ip          : managerIp,
                    cmac_in_port     : '80',
                    cmac_out_port    : managerPort,
                    cmac_network     : userNetwork,
                    cmac_cmaid       : applicationId,
                    cmac_create_time : common.nowTime(false),
                    cmac_uid         : bodyParams.cma_uid,
                    cmac_type        : '2'
                }
            },
            function (data) {
    
                actionLogs.push("操作记录：=> 管理层应用容器信息保存成功");
    
                actionLogs.push("操作记录：=> 应用已创建成功");
    
                cb();
    
            }
        )
    }

    /*
     * 当某一项出现问题，进行手动回滚之前重要操作
     * 待开发
     */
    function rollBackAllAction(cb){

        cb();

    }
    

    F.Serial([
       
        searchUserNetworkInfo,                  //查询用户网络的IP与端口使用范围（判断用户是否生成了用户网络）
        searchUserInfo,                         //获取用户配额信息  
        searchUserApplication,                  //判断该用户的应用相关限制
        addUserApplication,                     //新增用户应用基本信息
        addUserApplicationQuotaConfig,          //根据应用类型生成应用的配额配置信息
        createApplicationDb,                    //根据用户选择的产品类型创建独立数据库
        searchUserUsedIpAndPort,                //获取用户已使用的端口以及IP地址
        createAtomicApplicationBussiness,       //根据用户所选则的应用产品，复制相关的原子层应用业务到用户的项目目录（不含主框架部分）
        createAtomicLayerContainer,             //创建原子层服务容器
        createAtomicContainerRecord,            //保存应用原子层容器信息
        createAggregationApplicationBussiness,  //根据用户所选则的应用产品，复制相关的聚合层应用业务到用户的项目目录（不含主框架部分）
        createAggregationLayerContainer,        //创建聚合层服务容器
        createAggregationContainerRecord,       //保存应用聚合层容器信息
        createManagerApplicationBussiness,      //根据应用类型创建管理层项目到主项目目录
        createManagerLayerContainer,            //创建管理层服务容器
        updateManagerRequestIp,                 //修改管理层所要访问的聚合层IP地址写入，管理层的动态IP配置文件
        createManagerContainerRecord,           //保存应用管理层容器信息
        rollBackAllAction                       //当某一项出现问题，进行手动回滚之前重要操作
    
    ],() => {

        //将最终结果返回给客户端
        RES.successResponse(res,actionLogs);
    
    })


}